package engine;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import treetagger.FrenchTokenizer;

public class Request {

    private String request;
    private HashMap<String, Integer> tfMap;//Terme Frequency
    private HashMap<String, Double> wieghts;//poids = tf.idf = tf*log(N/df) avec N = nb docs

    public Request(String request) {
        this.request = request;
    }

    public HashMap<String, Double> getWieghts() {
        return wieghts;
    }

    public String getRequest() {
        return request;
    }
    
    //Affiche les poids de la requete
    @Override
    public String toString() {
        DecimalFormat df = new DecimalFormat("0.##");
        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.FRANCE);
        dfs.setDecimalSeparator('.');
        df.setDecimalFormatSymbols(dfs);

        String toPrint = "";

        toPrint += "{";
        for (Map.Entry<String, Double> entry : this.wieghts.entrySet()) {
            toPrint += df.format(entry.getValue()) + ", ";

        }
        toPrint = toPrint.substring(0, toPrint.length() - 1); //suppr dernière virgule
        toPrint += "}";

        return toPrint;
    }

    public void fillTfMap() {
        //FrenchTokenizer
        FrenchTokenizer ft = new FrenchTokenizer();

        this.tfMap = new HashMap<String, Integer>();
        //Parcours de chaque mot de la requete et ajout dans tfMap
        int frequency;
        for (String word : ft.tokenize(request.toLowerCase())) {
            frequency = tfMap.containsKey(word) ? tfMap.get(word) + 1 : 1;
            tfMap.put(word, frequency);
        }
    }

    public void fillWeights(Corpus corpus) {
        if (this.tfMap == null || corpus.getDfMap() == null) {
            return;
        }

        this.wieghts = new HashMap<String, Double>();

        //Nombre de documents
        int N = corpus.getDfMap().size();

        double sum = 0;
        for (Map.Entry<String, Integer> entry : corpus.getTfMap().entrySet()) {
            double tf = (double) (this.tfMap.containsKey(entry.getKey()) ? this.tfMap.get(entry.getKey()) : 0);
            double df = (double) corpus.getDfMap().get(entry.getKey());// = 0. si le mot n'existe dans aucun doc
            double tfIdf = (df == 0.) ? 0 : tf * Math.log10((double) N / df);

            this.wieghts.put(entry.getKey(), tfIdf);
            sum += tfIdf;
            //System.out.println(entry.getKey() + "   :TF="+tf+"; N/Df ="+ Math.log10((double) N / (double) df));
        }

        //Normalisation
        for (Map.Entry<String, Double> entry : this.wieghts.entrySet()) {
            this.wieghts.put(entry.getKey(), (sum == 0.) ? 0 : entry.getValue() / sum);
        }
    }
}
